# coding: UTF-8
import os
import sys
import time
import json
import shutil
import fnmatch
import tarfile
import zipfile
import datetime
import requests
import platform
from downloader import MultiCoroutineDownloader


def get_url(branch, product):
    '''
    获取给定分支上对应产品的下载地址
    @param branch: 分支
    @param product: 产品名
    '''
    
    # 各种产品对应的标志
    product_flags = {
        "ohos-sdk": "ohos-sdk.tar.gz",
        "mac-sdk-full": "L2-SDK-MAC-FULL.tar.gz",
        "mac-sdk-m1-full": "L2-SDK-MAC-M1-FULL.tar.gz",
        "dayu200": "dayu200_img.tar.gz"
    }
    if product not in product_flags:
        return None

    # 获取下载产品的url
    now_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    last_time = (datetime.datetime.now() + datetime.timedelta(hours=-24)).strftime("%Y%m%d%H%M%S")
    base_url = "http://ci.openharmony.cn/api/ci-backend/ci-portal/v1/dailybuilds"
    post_data = {
        "pageNum": 1,
        "pageSize": 1000,
        "startTime": str(last_time),
        "endTime": str(now_time),
        "projectName": "openharmony",
        "branch": str(branch),
        "component": "",
        "deviceLevel": "",
        "hardwareBoard": "",
        "buildStatus": "success",
        "buildFailReason": "",
        "testResult": ""
    }

    response = requests.post(base_url, post_data)
    data = json.loads(response.text)
    url_suffix = ""
    for info_dict in data["result"]["dailyBuildVos"]:
        if (info_dict.get("imgObsPath") is not None) and (product_flags[product] in info_dict["imgObsPath"]):
            url_suffix = info_dict["imgObsPath"]
            break
        elif ("obsPath" in info_dict) and (product_flags[product] in info_dict["obsPath"]):
            url_suffix = info_dict["obsPath"]
            break
    if url_suffix == "":
        return None
    return "http://download.ci.openharmony.cn/" + url_suffix


def deep_unpack(cur_file):
    '''
    cur_file: 要递归解压的文件名或者文件夹；若是文件夹，则对其下的所有
                        压缩文件递归解压
    '''
    cur_path = os.getcwd()
    if fnmatch.fnmatch(cur_file, "*.tar.gz"):
        base_path = os.path.split(cur_file)[0]
        os.chdir(base_path)
        next_file = cur_file[:-7]
        with tarfile.open(cur_file) as tar_file:
            direct_files = list(set([ item.split('/')[0] for item in tar_file.getnames()]))
            if len(direct_files) == 1:
                tar_file.extractall()
                next_file = os.path.join(base_path, direct_files[0])
            else:
                tar_file.extractall(next_file)
        deep_unpack(next_file)
    elif fnmatch.fnmatch(cur_file, "*.zip"):
        base_path = os.path.split(cur_file)[0]
        os.chdir(base_path)
        next_file = cur_file[:-4]
        zip_file = zipfile.ZipFile(cur_file)
        direct_files = list(set([ item.split('/')[0] for item in zip_file.namelist()]))
        if len(direct_files) == 1:
            zip_file.extractall()
            next_file = os.path.join(base_path, direct_files[0])
        else:
            zip_file.extractall(next_file)
        zip_file.close()
        deep_unpack(next_file)
    elif os.path.isdir(cur_file):
        for item in os.listdir(cur_file):
            realpath = os.path.join(cur_file, item)
            deep_unpack(realpath)
    os.chdir(cur_path)


if __name__ == "__main__":
    uname = platform.uname()
    branch = "master"                                                                    # 分支名
    script_path = sys.path[0]                                                            # 脚本所在目录
    product = "ohos-sdk"                                                                 # 产品名
    if uname.system == "Darwin":
        sdk_path = os.path.join(script_path, "Sdk")
        if uname.version.find("RELEASE_ARM64"):
            product = "mac-sdk-m1-full"
        else:
            product = "mac-sdk-full"

    filename = product + ".tar.gz"                                                       # 下载后的文件名
    store_path = os.path.join(script_path, "store")                                      # 用于临时存储下载的文件
    file_path = os.path.join(store_path, filename)                                       # 下载后的文件绝对路径
    sdk_path = "D:\\Software\\DevEcoSDK\\AutoTest\\Sdk\\10"                              # sdk所在目录
    sdk_src_path = os.path.join(store_path, product, "ohos-sdk", "windows")              # sdk解压后的目录
    if uname.system == "Darwin":
        sdk_path = os.path.join(script_path, "Sdk")
        sdk_src_path = os.path.join(store_path, "sdk", "packages", "ohos-sdk", "darwin")
    npm_ets_path = os.path.join(sdk_path, "ets", "build-tools", "ets-loader")            # ets执行npminstall的目录
    npm_js_path = os.path.join(sdk_path, "js", "build-tools", "ace-loader")              # js执行npminstall的目录
    
    # 0. 初始化
    print("开始替换，当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    if (os.path.exists(store_path)):
        shutil.rmtree(store_path, ignore_errors=True)
    os.makedirs(store_path)
    print(store_path, "删除成功！")
    if (os.path.exists(sdk_path)):
        shutil.rmtree(sdk_path, ignore_errors=True)
    os.makedirs(sdk_path)
    print(sdk_path, "删除成功！")

    # 1. 获取url
    url = get_url(branch, product)
    if url is None:
        print("未获取到%s分支上%s的下载链接" %(branch, product))
        exit(-1)
    print("%s分支上%s的下载链接为: %s" %(branch, product, url))
    
    # 2. 下载文件
    print("开始下载, 当前时间为: %s, 文件将存放于: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), store_path))
    downloader = MultiCoroutineDownloader(url, file_path)
    downloader.start()

    # 3. 解压文件
    print("开始解压: 当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    deep_unpack(file_path)

    # 4. 拷贝文件
    print("开始拷贝: 当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    sub_parts = ["ets", "js", "native", "previewer", "toolchains"]
    for item in sub_parts:
        src_path = os.path.join(sdk_src_path, item)
        dist_path = os.path.join(sdk_path, item)
        shutil.copytree(src_path, dist_path)

    # 5. 执行npm install
    print("ets目录下执行npm install, 当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    os.chdir(npm_ets_path)
    os.system("npm install")
    print("js目录下执行npm install, 当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    os.chdir(npm_js_path)
    os.system("npm install")

    print("结束替换，当前时间为: %s" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    